﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;

namespace Ko2.DB
{

    public partial class OneC : OneCBase
    {

        #region Members

        public enum OrgStructure_Level_0_Names { Все = 0, АУП = 1, Магазины = 2 };

        #endregion

        #region Common Methods
        private Exception OrgStructure_MakeTable(ref DataTable tbl)
        {
            Exception ret = null;
            tbl = null;
            tbl = new DataTable("tbl");
            tbl.Columns.Add("Name", typeof(string));
            tbl.Columns.Add("ID", typeof(int));
            tbl.Columns.Add("ParentID", typeof(int));
            return ret;
        }
        private Exception OrgStructure_AddRow(DataRow srcRow, ref DataTable dest)
        {
            Exception ret = null;
            DataRow newr = dest.NewRow();
            foreach (DataColumn c in srcRow.Table.Columns)
                newr[c.Caption] = srcRow[c.Caption];
            dest.Rows.Add(newr);
            return ret;
        }
        public Exception OrgStructure_FillTreeCtrl(ref DataTable TblSrc, ref System.Windows.Forms.TreeView tree)
        {
            Exception ret = null;

            try
            {

                string sTmp = TblSrc.DefaultView.Sort;
                bool bSkiped = false;
                if (!String.IsNullOrEmpty(sTmp))
                    TblSrc.DefaultView.Sort = "";

                DataTable tblSkiped = new DataTable("Skiped");
                OrgStructure_MakeTable(ref tblSkiped);
                DataTable tblSkiped2 = new DataTable("Skiped2");
                OrgStructure_MakeTable(ref tblSkiped2);
                
                foreach (DataRow r in TblSrc.Rows)
                {
                    string Name = "";
                    if (r["Name"] != DBNull.Value)
                        Name = (string)r["Name"];
                    int? ID = null;
                    if (r["ID"] != DBNull.Value)
                        ID = (int)r["ID"];
                    int? ParentID = null;
                    if (r["ParentID"] != DBNull.Value)
                        ParentID = (int)r["ParentID"];

                    bSkiped = false;
                    OrgStructure_FillTreeCtrl_AddNode(Name, ID, ParentID, ref tree, ref bSkiped);
                    if (bSkiped)
                        OrgStructure_AddRow(r, ref tblSkiped);
                }

                foreach (DataRow r in tblSkiped.Rows)
                {
                    string Name = "";
                    if (r["Name"] != DBNull.Value)
                        Name = (string)r["Name"];
                    int? ID = null;
                    if (r["ID"] != DBNull.Value)
                        ID = (int)r["ID"];
                    int? ParentID = null;
                    if (r["ParentID"] != DBNull.Value)
                        ParentID = (int)r["ParentID"];

                    bSkiped = false;
                    OrgStructure_FillTreeCtrl_AddNode(Name, ID, ParentID, ref tree, ref bSkiped);
                    if (bSkiped)
                        OrgStructure_AddRow(r, ref tblSkiped2);
                }

                foreach (DataRow r in tblSkiped2.Rows)
                {
                    string Name = "";
                    if (r["Name"] != DBNull.Value)
                        Name = (string)r["Name"];
                    int? ID = null;
                    if (r["ID"] != DBNull.Value)
                        ID = (int)r["ID"];
                    int? ParentID = null;
                    if (r["ParentID"] != DBNull.Value)
                        ParentID = (int)r["ParentID"];

                    bSkiped = false;
                    OrgStructure_FillTreeCtrl_AddNode(Name, ID, ParentID, ref tree, ref bSkiped);
                }

            }
            catch (Exception err)
            {
                ret = new Exception(err.Message, err);
            }

            return ret;
        }
        private Exception OrgStructure_FillTreeCtrl_AddNode(string Name, int? ID, int? ParentID, ref System.Windows.Forms.TreeView tree, ref bool bSkiped)
        {
            Exception ret = null;

            if(ID == null)
                return ret;

            string idStr = ID.ToString();

            if (ParentID == null)
            {
                System.Windows.Forms.TreeNode newnode = tree.Nodes.Add(Name);
                newnode.Tag = idStr;
            }
            else
            {
                System.Windows.Forms.TreeNode parentNode = null;
                bool IsFind = false;
                ret = OrgStructure_FillTreeCtrl_FindNode(ref tree, ref parentNode, ref IsFind, ParentID);
                if (IsFind == true)
                {
                    System.Windows.Forms.TreeNode newnode = parentNode.Nodes.Add(Name);
                    newnode.Tag = idStr;
                }
                else
                {
                    //System.Windows.Forms.TreeNode newnode = tree.Nodes.Add(Name);
                    //newnode.Tag = idStr;
                    bSkiped = true;
                }
            }

            return ret;
        }
        private Exception OrgStructure_FillTreeCtrl_FindNode(ref System.Windows.Forms.TreeView tree, ref System.Windows.Forms.TreeNode node, ref bool IsFind, int? ID)
        {
            Exception ret = null;
            IsFind = false;
            foreach(System.Windows.Forms.TreeNode n in tree.Nodes)
            {
                string tag = (string)n.Tag;
                if (tag == ID.ToString())
                {
                    node = n;
                    IsFind = true;
                    return ret;
                }
                ret = OrgStructure_FillTreeCtrl_FindNode2(ref node, n, ref IsFind, ID);
                if (ret != null)
                    return ret;
                if (IsFind)
                    return ret;
            }
            return ret;
        }
        private Exception OrgStructure_FillTreeCtrl_FindNode2(ref System.Windows.Forms.TreeNode node, System.Windows.Forms.TreeNode nodeSrc, ref bool IsFind, int? ID)
        {
            Exception ret = null;
            IsFind = false;
            foreach (System.Windows.Forms.TreeNode n in nodeSrc.Nodes)
            {
                string tag = (string)n.Tag;
                if (tag == ID.ToString())
                {
                    node = n;
                    IsFind = true;
                    return ret;
                }
                ret = OrgStructure_FillTreeCtrl_FindNode2(ref node, n, ref IsFind, ID);
                if (ret != null)
                    return ret;
                if (IsFind)
                    return ret;
            }
            return ret;
        }
        public Exception OrgStructure_MakeXml(ref DataTable TblSrc, ref XmlDocument xDoc)
        {
            Exception ret = null;
            //try
            //{
                XmlNode rootNode = xDoc.CreateElement("OrgNodes");
                xDoc.AppendChild(rootNode);

                string sTmp = TblSrc.DefaultView.Sort;
                bool bSkiped = false;
                if (!String.IsNullOrEmpty(sTmp))
                    TblSrc.DefaultView.Sort = "";

                foreach (DataRow r in TblSrc.Rows)
                {
                    string Name = "";
                    if (r["Name"] != DBNull.Value)
                        Name = (string)r["Name"];
                    int? ID = null;
                    if (r["ID"] != DBNull.Value)
                        ID = (int)r["ID"];
                    int? ParentID = null;
                    if (r["ParentID"] != DBNull.Value)
                        ParentID = (int)r["ParentID"];

                    bSkiped = false;
                    OrgStructure_MakeXml_AddNode(Name, ID, ParentID, ref xDoc, ref bSkiped);
                    //if (bSkiped)
                    //    OrgStructure_AddRow(r, ref tblSkiped);
                }

            //}
            //catch (Exception err)
            //{
            //    ret = new Exception(err.Message, err);
            //}

            return ret;
        }
        private Exception OrgStructure_MakeXml_AddNode(string Name, int? ID, int? ParentID, ref XmlDocument xDoc, ref bool bSkiped)
        {
            Exception ret = null;

            if (ID == null)
                return ret;

            string idStr = ID.ToString();

            if (ParentID == null)
            {
                XmlNode node = xDoc.CreateElement("_" + ID.ToString());
                node.InnerText = "_" + ID.ToString();
                XmlAttribute attr_id = xDoc.CreateAttribute("ID");
                attr_id.Value = ID.ToString();
                node.Attributes.Append(attr_id);
                XmlAttribute attrParentID = xDoc.CreateAttribute("ParentID");
                attrParentID.Value = "";
                node.Attributes.Append(attrParentID);
                XmlAttribute attrName = xDoc.CreateAttribute("Name");
                attrName.Value = Name;
                node.Attributes.Append(attrName);
                xDoc.ChildNodes[0].AppendChild(node);
            }
            else
            {
                XmlNode parentNode = null;
                bool IsFind = false;
                ret = OrgStructure_MakeXml_FindNode(ref xDoc, ref parentNode, ref IsFind, ParentID);
                if (IsFind == true)
                {
                    XmlNode node = xDoc.CreateElement("_" + ID.ToString());
                    node.InnerText = "_" + ID.ToString();
                    XmlAttribute attr_id = xDoc.CreateAttribute("ID");
                    attr_id.Value = ID.ToString();
                    node.Attributes.Append(attr_id);
                    XmlAttribute attrParentID = xDoc.CreateAttribute("ParentID");
                    attrParentID.Value = ParentID.ToString();
                    node.Attributes.Append(attrParentID);
                    XmlAttribute attrName = xDoc.CreateAttribute("Name");
                    attrName.Value = Name;
                    node.Attributes.Append(attrName);
                    parentNode.AppendChild(node);
                }
                else
                {
                    bSkiped = true;
                }
            }

            return ret;
        }
        private Exception OrgStructure_MakeXml_FindNode(ref XmlDocument xDoc, ref XmlNode node, ref bool IsFind, int? ID)
        {
            Exception ret = null;
            IsFind = false;
            foreach (XmlNode n in xDoc.ChildNodes)
            {
                if (n.Attributes.Count == 0 && n.ChildNodes.Count > 0)
                {
                    ret = OrgStructure_MakeXml_FindNode2(ref node, n, ref IsFind, ID);
                    if (ret != null)
                        return ret;
                    if (IsFind)
                        return ret;
                    continue;
                }
                string attrID = (string)n.Attributes["ID"].Value;
                if (attrID == ID.ToString())
                {
                    node = n;
                    IsFind = true;
                    return ret;
                }
                ret = OrgStructure_MakeXml_FindNode2(ref node, n, ref IsFind, ID);
                if (ret != null)
                    return ret;
                if (IsFind)
                    return ret;
            }
            return ret;
        }
        private Exception OrgStructure_MakeXml_FindNode2(ref XmlNode node, XmlNode nodeSrc, ref bool IsFind, int? ID)
        {
            Exception ret = null;
            IsFind = false;
            if (nodeSrc.ChildNodes.Count > 0)
            {
                foreach (XmlNode n in nodeSrc.ChildNodes)
                {
                    if (n.Attributes == null)
                        continue;
                    string attrID = (string)n.Attributes["ID"].Value;
                    if (attrID == ID.ToString())
                    {
                        node = n;
                        IsFind = true;
                        return ret;
                    }
                    ret = OrgStructure_MakeXml_FindNode2(ref node, n, ref IsFind, ID);
                    if (ret != null)
                        return ret;
                    if (IsFind)
                        return ret;
                }
            }
            return ret;
        }
        #endregion

        #region Get
        public Exception GetOrgStructure(ref DataTable tbl, OrgStructure_Level_0_Names level_0)
        {
            Exception ret = null;
            DataTable tblTmp = new DataTable("tbl");
            ret = GetOrgStructure_Level_0(ref tblTmp, level_0);
            if (ret != null)
                return ret;
            OrgStructure_MakeTable(ref tbl);
            foreach (DataRow r in tblTmp.Rows)
            {
                if (r["Name"] != DBNull.Value)
                {
                    if (level_0 == OrgStructure_Level_0_Names.Все)
                        OrgStructure_AddRow(r, ref tbl);
                    else if (level_0 == OrgStructure_Level_0_Names.АУП && (string)r["Name"] == "АУП")
                        OrgStructure_AddRow(r, ref tbl);
                    else if (level_0 == OrgStructure_Level_0_Names.Магазины && (string)r["Name"] == "Магазины")
                        OrgStructure_AddRow(r, ref tbl);
                }
            }

            DataTable tblTmp3 = new DataTable("tbl3");
            OrgStructure_MakeTable(ref tblTmp3);

            foreach (DataRow r in tbl.Rows)
            {
                DataTable tblTmp2 = new DataTable("tbl2");
                OrgStructure_MakeTable(ref tblTmp2);
                ret = GetOrgStructure_ParentNode(ref tblTmp2, r);
                if (ret != null)
                    return ret;
                foreach (DataRow r2 in tblTmp2.Rows)
                    OrgStructure_AddRow(r2, ref tblTmp3);
            }

            foreach (DataRow r2 in tblTmp3.Rows)
                OrgStructure_AddRow(r2, ref tbl);

            return ret;
        }
        private Exception GetOrgStructure_Level_0(ref DataTable tbl, OrgStructure_Level_0_Names level_0)
        {
            Exception ret = null;
            string ConnStr = _env.GetAppSetting("1CConnect");
            string sql =
@"SELECT sp._Description as Name,sp._Code as ID,sp1._Code as ParentID 
FROM _Reference67 as sp 
LEFT JOIN _Reference67 as sp1 ON sp1._IDRRef=sp._ParentIDRRef 
WHERE sp._Code<>'09' AND sp1._Code Is Null";
            ret = GetTable(ref tbl, ConnStr, sql);
            return ret;
        }
        private Exception GetOrgStructure_ParentNode(ref DataTable tbl, DataRow row)
        {
            Exception ret = null;
            string Name = "";
            if(row["Name"] != DBNull.Value)
                Name = (string)row["Name"];
            int? ID = null;
            if (row["ID"] != DBNull.Value)
                ID = (int)row["ID"];
            int? ParentID = null;
            if (row["ParentID"] != DBNull.Value)
                ParentID = (int)row["ParentID"];

            DataTable tblTmp = new DataTable("tbl");
            OrgStructure_MakeTable(ref tblTmp);
            ret = GetOrgStructure_ParentNode(ref tblTmp, ID);

            foreach (DataRow r in tblTmp.Rows)
                OrgStructure_AddRow(r, ref tbl);

            foreach (DataRow r in tblTmp.Rows)
                GetOrgStructure_ParentNode(ref tbl, r);

            return ret;
        }
        private Exception GetOrgStructure_ParentNode(ref DataTable tbl, int? ID)
        {
            Exception ret = null;
            string ConnStr = _env.GetAppSetting("1CConnect");
            string sql =
@"SELECT sp._Description as Name,sp._Code as ID,sp1._Code as ParentID 
FROM _Reference67 as sp 
LEFT JOIN _Reference67 as sp1 ON sp1._IDRRef=sp._ParentIDRRef 
WHERE sp._Code<>'09' AND sp1._Code " + (string)(ID == null ? " Is Null " : " = " + ID.ToString());
            ret = GetTable(ref tbl, ConnStr, sql);
            return ret;
        }
        #endregion

    }

}
